
package com.huawei.housekeeper.config.datasource;

import com.huawei.housekeeper.dao.entities.MigrationInformation;

import lombok.extern.log4j.Log4j2;

import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationState;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * flyway加载数据源完成迁移
 *
 * @author lWX1128557
 * @since 2022-03-10
 */
@Component
@RefreshScope
@Log4j2
public class DataSourceConfiguration {

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.url}")
    private String url;

    /**
     * flyway版本迁移--所有租户
     *
     * @param schemas 租户Schema
     * @return 迁移信息
     */
    public MigrationInformation migration(List<String> schemas) {
        Map<String, String> failInfo = new HashMap<>();
        int success = 0;
        int fail = 0;
        for (String schema : schemas) {
            try {
                Flyway.configure().dataSource(url, username, password).schemas(schema).load().migrate();
                success++;
            } catch (Exception e) {
                Flyway flyway = Flyway.configure().dataSource(url, username, password).schemas(schema).load();
                Arrays.stream(flyway.info().all()).forEach(m -> {
                    if (m.getState().isFailed()) {
                        failInfo.put(schema + " " + m.getVersion().getVersion(), "---> 脚本迁移失败");
                    } else if (m.getState().isResolved() && !m.getState().isApplied()
                        && m.getState().getDisplayName().equals(MigrationState.IGNORED.getDisplayName())) {
                        failInfo.put(schema + " " + m.getVersion().getVersion(), "---> 找到这个脚本，但是版本记录表中没有这个版本");
                    } else if (!m.getState().isResolved() && m.getState().isApplied()
                        && m.getState().getDisplayName().equals(MigrationState.MISSING_SUCCESS.getDisplayName())) {
                        failInfo.put(schema + " " + m.getVersion().getVersion(), "---> 没有这个脚本，但版本记录表中找到这个版本");
                    }
                });
                fail++;
                log.error(e.getMessage(), e);
            }
        }

        // 脚本迁移
        return new MigrationInformation(schemas.size(), failInfo, success, fail);
    }

    /**
     * flyway数据库脚本迁移--新建租户
     *
     * @param schema 租户 tenantSchema
     */
    public void migration(String schema) {
        // 脚本迁移
        Flyway.configure().dataSource(url, username, password).schemas(schema).load().migrate();
    }
}
